Picking up from the last lesson, we are now able to open items for reading and close them, but as
discussed, we want to add the ability to not only close an item, but also delete it at the same time.
Starting back in reading of the script being evaluated in our remote item content, we can add the button
to mark an item as done.
A sign the Neubauten element to a variable of redit close, creating it with document, create aliment,
make the button a simple div.
With a label of done implying we're done with an item and it can also be removed at some styles to have
this development resemble a button.
Setting its position to fixed.
Copy the style property.
Bottom to 15 pixels, so 15 pixels from the bottom of the parent container being the body tag, once
we append this element to it, same 15 pixels from the right, some padding, five pixels top and bottom
and 10 pixels left and right, font size can be 20 pixels important to keep this font size as an absolute
size and not a relative or percentage value as that will then vary depending on the remote contents,
font size, something to keep in mind as we're adding this button to an essentially unknown environment
font weight to bold.
With a Dodger blue button background.
White text on that blue button.
A slight radius to the bottom corners, five pixels make the cursor display an arrow when hovering over
the button with cursor default and lastly, separate the button from the content behind it by applying
a slight shadow to pixels by two pixels with a two pixel blur and a very transparent black nought point
two percent opaque.
That's the button styled.
So, as mentioned, append this to the remote content body element.
Remember, this script is executed in the remote content scope, so select the body element as you'd
normally do with document aget elements by tag name body accessing the first element as there can only
be one body tag append child redit close this dev button test.
This works and looks right.
Open an item to have the script inject it and the button gets added, although it's behind this content,
which we can fix with a Z index in a second, but more importantly, over the dev tools, we have this
error with the important part being this line here, an object could not be cloned.
Now, going into detail as to what exactly is happening here might take a bit long.
But essentially this is a result of the internal IPC communication that's happening when this proxy
browser window is created.
We see here IPSI Renderer internal invoke that same invoke method we saw when covering IPSI in an earlier
lesson.
And the simple reason an item could not be cloned is as IPSI can only transfer or clone regular JavaScript
objects, things that can be serialized.
And in our reader dodgiest file append child is in fact returning a non-standard JavaScript object,
an HTML dom node object to be exact, something that cannot be serialized.
So the reason I chose to use this then is as it will be, the most obvious solution for what we are
trying to do here.
And every now and again, you will run into small errors like this simply because of how electron handles
internal communication.
If you'd like to understand the technicals of this a bit better, I've linked to some documentation
explaining it.
But for our purposes we can do one of a few other options.
We can either append this new button element as a string to the bodies in our HTML or the best alternative
use the new append method like this.
Append, unlike a child, doesn't create an HTML note object, so it solves the internal IPCC serialization
issue.
And before we test this again, we can also give this button element a Z index of nine nine nine nine
just to force it to the front of that remote content safe and try again.
Open the item.
And there this now works, so again, whilst that might seem like an odd issue, which it probably is,
I just particularly wanted to show it so that you're aware of the small internal workarounds that might
be necessary every now and again, right back to where we were.
We now have this button in the remote content, but it doesn't actually do anything.
So let's go ahead and attach a click listener to this.
This time using the element unclick attribute.
Equal to a function with the click event in which will simply display an alert for now done with item
safe to test again.
Open an item as before, which gets the button added a moment later, click and the rear window shows
that alert.
So our button is now hooked up, meaning the next step is to communicate with the main window.
Keep in mind that we don't have access to IPSI messaging or the main window context from within the
reader window.
So instead we can use HTML5 messaging API.
This API allows us to send a message to any window instance, meaning as long as we can get a reference
to the main window, we can securely send a message to it.
And with this reader window being a proxy browser window, Electron provides us a reference to the window
responsible for opening it, accessing on window the opener property opener being a safe reference to
the main window.
Send a message to that main window with post message.
With a message of Eitam done to any target origin indicated by the asterisk, we'll have to listen for
this message in the main window or items stogies as that's required by the main window.
Right at the top here, listen for Dunn, message from reader window.
Listening on the window object with the standard ad event, listener for message.
At a callback on this message listener in which we can log out the message data by accessing it on the
event object e data.
Save both files.
Open an item.
I'll move this reader window out the way so we can observe the main Windows console click done and we
see the message sent from the reader window in our main up window item done.
OK, so now being able to tell our app that we are done with the item, let's add the code to delete
an item at a certain index.
Remember, the main window has no way of knowing which item this message is referring to.
So along with the message, we'll have to tell it.
And the easiest way to do this is going to be giving it the item index.
That said, the reader window itself doesn't know which item it's dealing with at the moment.
The reader window is simply created to load a given URL, so we'll have to inject the item index along
with that button code, step one being to get the actual index of an item.
I'll create a new function for this export get selected item being that when an item is opened, that
item is also selected.
As before, get this selected node.
Let current item equals document, get elements by class name.
Read items selected.
Item one or index zero, then using a simple loop, we can determine the index of the selected item
in its parent container.
Start by setting item index zero.
Add child equal to current item.
Looping worthwhile.
The child element equal to the previous sibling of itself, so attempting to set this child variable
to its own previous sibling, and if it's not equal to null, meaning a previous sibling exists, increment
the item index by one.
This might look a bit odd, but it's pretty straightforward.
For example, if the selected item, this current item is the first item, it won't have a previous
sibling setting child to null on the first loop iteration, which will leave the item index at zero
or position one.
If, however, had had one previous sibling, it would increment once and be at index one and so on.
Then having the selected items index, we can finally return both the item index and the selected item
node as an object.
Return an object with key node equal to the selected item and key index equal to item index.
The value we calculated here.
We can also now use this function instead of all the references to the currently selected item, just
to clean things up a bit.
Copy.
First election here, where we simply remove the items, selected class, replace the Selecter with
this dog, get selected item dog node being the selected item just a bit cleaner, we have a few more
of these.
So Kopi, this year in the change election function, set current item to this dog gets selected item
accessing in the function current item dot node like so.
Same in our open function.
Selected item.
Selected Item A..
And that's it.
OK, back in the message, listener now having a way to access an item's index, we can call in this
function, this dot delete a function.
We still have to create passing in the reader Windows item index from the message.
Again, something we still have to add.
I'll say e dot data item index, copy this property name so we can set it on our message.
That message, of course, coming from this reader is so back to the reader dodgier script.
Make this message an object instead of the simple string with an action property delete reader item,
this just being a simple way of identifying the message in items dodges as we're listening for all messages
in there and item index, which of course we don't have in the script.
So we'll have to dynamically set it.
I'll make this a unique tag that we can replace with the item index, double Brackett's index, then
back in items charges when opening an item.
This reader Jayesh Content will now contain that index tag.
So having access to the selected item index here simply replace that tag in the reader gesturing with
the item index.
Calling on Rita James, replace the standard JavaScript string, replace function double Brackett's
index, that tag, we just add it with the selected items index or the item being opened selected item
DOT index.
So now when clicking, the done button will get an object sent via the message event with the item index
to delete.
We can test this in the message callback temporarily replace this call to delete as that doesn't exist
yet with console dot log e dot data.
That message object we're sending from the remote content, save both files, open the first item.
So index zero Ilagan resize this down so we can see the main Windows console click done and there the
action as we set it and the item index of zero.
Try an item at a different index.
I'll close this open.
No just this time.
So index to.
Click done and again, this works as expected, so we now have our Eitam index, meaning we can close
and delete an item when receiving the message from the Dunbarton back in items dot undo this log to
again, call that delete function, which we can now implement.
But before we do, let's also make sure this message event is in fact the correct message, just as
a precaution.
If IDOT DataDot action equals delete reader item.
Call this delete function with the item index.
After which meaning the item has been deleted, close the reader window for the user.
This, of course, means again, that we need a reference to the proxy window or the sender of this
message, which we can access on the message event as source.
I log that out to demonstrate.
Save.
Open an item.
Done and there a browser window proxy, which, if we expand it contains the standard browser window,
close function.
So to close the reader window after deleting the item, call each source dot, close save and test.
I'll do electron this time.
Click the button and the window is closed, but not yet deleted.
So let's finally add that delete function.
Now I'll uncommented this again, create the function delete item.
Export the lead with a single argument being the item to delete index.
First thing being to remove the item from the DOM.
Calling on the items container aliment, remove child, this takes the note to delete, so get all the
items in the items div with items, child notes, child notes, returns, an array of elements or items.
So item at index, item index, this argument that visually removes the item from our app, but it's
still present in the storage array.
So to remove it completely say this storage splice item index, one element this just saying cut from
this array, one element starting at this index and lastly persist the storage array to save those changes.
This stored save.
That's the item removal done, but when we delete this item, we no longer have a selected item, so
we'll have to select another.
The most logical way to do this is going to be selecting either the previous item in the list or if
it was the first item in the list to be deleted, simply select the element now in the first place.
There's also the possibility of the deleted item having been the last item, meaning there's nothing
else to select to avoid that.
Start by checking if we still have items left.
If this storage length, meaning we have one or more items in the storage array, go ahead and select
a new item based on the index of the deleted item.
Let new selected item index equal using a ternary operator to check if we deleted the first item or
not, if item index equal to zero, meaning it was the first item, said the newly selected item index,
to now be zero as well as we want to select the item now at the top else, meaning we have one or more
items previous to the now deleted item, said the new selected item index to item index minus one one
up.
Select the item at that new index.
First, getting all of the read items with document, get elements by class, name read items sitting
on the item at the new selected item index with class list dot add selected.
That should do all save this.
Open an item electron.
I'll move this over to the right this time so we can see the items when I click done.
Click and gone, that electronic item is removed from both the app interface and from storage, with
the previous item automatically selected, that completes all of the apps item logic.
So in the next lesson will finalize this app by adding system menus and keyboard shortcuts.